export function isObject(v: unknown) {
  return typeof v === "object" && v !== null;
}

export class MemoizeMap {
  // 定义一个Map对象，用于存储非对象类型的键值对
  private _map = new Map();
  // 定义一个WeakMap对象，用于存储对象类型的键值对
  private _weakMap = new WeakMap();

  /**
   * #### 判断一个值是否为对象
   * @static
   * @param v 要判断的值
   * @returns boolen 如果是对象，则返回true，否则返回false
   */
  // static isObject(v: unknown) {
  //   return typeof v === "object" && v !== null;
  // }

  // 设置键值对的方法
  set(key: unknown, value: unknown) {
    // 如果键是对象，则使用WeakMap存储
    if (isObject(key)) {
      this._weakMap.set(key, value);
      // 否则使用Map存储
    } else {
      this._map.set(key, value);
    }
  }

  // 获取键值对的方法
  get(key: unknown) {
    // 如果键是对象，则从WeakMap中获取
    if (isObject(key)) {
      return this._weakMap.get(key);
      // 否则从Map中获取
    } else {
      return this._map.get(key);
    }
  }

  // 判断键值对是否存在的方法
  has(key: unknown) {
    // 如果键是对象，则从WeakMap中判断
    if (isObject(key)) {
      return this._weakMap.has(key);
      // 否则从Map中判断
    } else {
      return this._map.has(key);
    }
  }
}

/**
 * #### 缓存函数的执行结果
 * @param func 要缓存的函数
 * @param resolver 解析器函数
 * @returns
 */
export function memoize(
  // 要缓存的函数
  func: (...args: any[]) => any,
  resolver?: (...args: any[]) => any
) {
  function memoized(...args: any[]) {
    const key = resolver ? resolver(...args) : args[0];
    const cache = memoized.cache;
    if (cache.has(key)) {
      return cache.get(key);
    }
    //@ts-ignore
    const result = func.apply(this, args);
    cache.set(key, result);
    return result;
  }
  memoized.cache = new MemoizeMap();
  return memoized;
}

const object = { a: 1, b: 2 };
const other = { c: 3, d: 4 };
const values = memoize((obj: object) => Object.values(obj));
console.log(values(object)); // [1, 2]
console.log(values(other)); // [3, 4]
object.a = 2;
console.log(values(object)); // [1, 2]
values.cache.set(object, ["a", "b"]);
console.log(values(object)); // ["a", "b"]
